<script setup lang="ts">
import { ref, reactive, watch } from 'vue';
import { ElForm, } from 'element-plus';
import type { FormConfig, ComponentAttrs,  } from '@/components/crud/types';
// 定义 props，接收表单配置、初始数据和 modelValue
const props = defineProps<{
  config: FormConfig[];
  initialData?: Record<string, any>;
  modelValue: Record<string, any>;
  hideButton?: boolean;
}>();

// 定义 emit 事件，添加 update:modelValue 用于双向绑定
const emit = defineEmits(['submit', 'cancel', 'update:modelValue']);

// 表单数据，合并初始数据和 modelValue
const formData = reactive<Record<string, any>>({ ...props.initialData, ...props.modelValue });
// 存储初始表单数据
const initialFormData = reactive<Record<string, any>>({ ...props.initialData, ...props.modelValue });

// 监听 modelValue 变化，同步更新 formData
watch(() => props.modelValue, (newValue) => {
  Object.assign(formData, newValue);
}, { deep: true });

// 表单验证规则
const rules = reactive<Record<string, any>>({});
props.config.forEach((item) => {
  if (item.rules) {
    rules[item.field] = item.rules;
  }
});

// 表单引用
const formRef = ref<InstanceType<typeof ElForm>>();
const validate =  () => {
  return new Promise((resolve, reject) => {
    formRef.value?.validate((valid, fields?: Object) => {
      if (valid) {
        resolve(true)
      } else {
          reject('验证未通过');
      }
    })
  })
}
// 提交表单
const handleSubmit = () => {
  formRef.value?.validate((valid) => {
    if (valid) {
      emit('submit', { ...formData });
    }
  });
};

// 取消操作
const handleCancel = () => {
  emit('cancel');
};

// 监听表单数据变化，更新 modelValue
watch(formData, (newValue) => {
  emit('update:modelValue', newValue);
}, { deep: true });

// 重置表单方法
const reset = () => {
  // 重置表单数据为初始值
  Object.assign(formData, initialFormData);
  // 清除表单验证状态
  formRef.value?.resetFields();
  // 触发更新 modelValue 事件
  emit('update:modelValue', { ...formData });
};
function getItemStyle(item: ComponentAttrs) {
  let style: Record<string, any> = {}
  if (typeof item.width === 'number') {
      style.width = item.width + 'px'
  }
  if (typeof item.width === 'string') {
      style.width = item.width
  }
  if (typeof item.height === 'number') {
      style.height = item.height + 'px'
  }
  if (typeof item.height ==='string') {
      style.height = item.height
  }
  return style
}
// 暴露方法
defineExpose({
  reset,
  validate
});
</script>

<template>
  <el-form
    ref="formRef"
    :model="formData"
    :rules="rules"
    label-width="120px"
    @submit.prevent="handleSubmit"
  >
    <template v-for="item in props.config" :key="item.field">
      <el-form-item :label="item.title" :prop="item.field">

        <component
            :is="item.component.name"
            v-model="formData[item.field]"
            :style="getItemStyle(item.component)"
            v-bind="item.component.attrs"
        />
      </el-form-item>
    </template>
    <el-form-item v-if="!hideButton">
      <el-button type="primary" @click="handleSubmit">提交</el-button>
      <el-button @click="handleCancel">取消</el-button>
    </el-form-item>
  </el-form>
</template>

<style scoped>
/* 可根据需要添加样式 */
</style>
